﻿//========================================================= 
/**@file ArgParser.cpp 
 * @brief base目录下ArgParser库中全局函数、变量的实现 
 * 
 * @date 2012-06-23   11:26:05 
 * @author Zhyioo 
 * @version 1.0
 */ 
//--------------------------------------------------------- 
#ifndef _LIBZHOUYB_ARGPARSER_CPP_
#define _LIBZHOUYB_ARGPARSER_CPP_
//--------------------------------------------------------- 
#include "../../base/DevDefine.h"
#include "../../base/Logger.h"
#include "../../base/ArgParser.h"
using namespace zhou_yb;
//---------------------------------------------------------
namespace zhou_yb {
namespace base {
//--------------------------------------------------------- 
// 转换的模板特化 
template<> const char* ArgConvert::FromString<const char*>(const string& str)
{
    return str.c_str();
}
template<> bool ArgConvert::FromString<char>(const string& str, char& val)
{
    if(str.length() < 1)
        return false;
    val = str[0];
    return true;
}
template<> bool ArgConvert::FromString<string>(const string& str, string& val)
{
    val = str;
    return true;
}
template<> bool ArgConvert::FromString<pointer>(const string& str, pointer& val)
{
    if(str.length() < 1 || StringConvert::Compare(str.c_str(), "NULL", true))
    {
        val = NULL;
        return true;
    }

    if(str.length() != (2+sizeof(pointer)) 
        && str[0] != '0'
        && _get_lower(str[1]) != 'x')
    {
        // 格式错误
        return false;
    }
    ByteBuilder tmpBuffer(8);
    ByteConvert::FromAscii(ByteArray(str.c_str() + 2, 2*sizeof(pointer)), tmpBuffer);
    ByteConvert::ToObject(tmpBuffer, val);
    return true;
}
template<> bool ArgConvert::FromString<ByteBuilder>(const string& str, ByteBuilder& val)
{
    DevCommand::FromAscii(ByteArray(str.c_str(), str.length()), val);
    return true;
}
template<> bool ArgConvert::FromString<bool>(const string& str, bool& val)
{
    int iVal = 0;
    FromString<int>(str, iVal);
    val = StringConvert::Compare(ByteArray(str.c_str(), str.length()), "true", true) || (iVal != 0);
    return true;
}
template<> bool ArgConvert::FromString<byte>(const string& str, byte& val)
{
    if(!StringConvert::StartWith(str.c_str(), "0x", true))
    {
        uint v = 0;
        ArgConvert::FromString<uint>(str, v);
        val = _itobyte(v);
        return true;
    }
    if(str.length() < 3 || str.length() > 4)
        return false;

    byte buff[2];
    if(str.length() == 4)
    {
        buff[0] = str[2];
        buff[1] = str[3];
    }
    else
    {
        buff[0] = 0;
        buff[1] = str[2];
    }
    ByteBuilder tmp(2);
    if(ByteConvert::FromAscii(ByteArray(buff, 2), tmp) < 1)
        return false;
    val = tmp[0];
    return true;
}
template<> string ArgConvert::ToString<char>(const char & val)
{
    string str;
    str += val;
    return str;
}
template<> string ArgConvert::ToString<string>(const string & val)
{
    return val;
}
template<> string ArgConvert::ToString<pointer>(const pointer & val)
{
    return _hex_num(val);
}
template<> string ArgConvert::ToString<ByteArray>(const ByteArray& val)
{
    if(val.IsEmpty())
        return "";
        
    ByteBuilder tmp(32);
    ByteConvert::ToAscii(val, tmp);
    
    return tmp.GetString();
}
template<> string ArgConvert::ToString<ByteBuilder>(const ByteBuilder& val)
{
    return ArgConvert::ToString<ByteArray>(val);
}
template<> string ArgConvert::ToString<bool>(const bool& val)
{
    return val ? "True" : "False";
}
template<> string ArgConvert::ToString<byte>(const byte& val)
{
    return ArgConvert::ToString<uint>(val);
}
//--------------------------------------------------------- 
/// 获取当前系统时间 
size_t get_current_systime(ByteBuilder& timebuff)
{
    // 输出当前系统时间
    time_t lt;
    time(&lt);
    tm t;
    size_t len = 0;

    // VC6下版本
    t = (*localtime(&lt));

    len = timebuff.Format("%04d-%02d-%02d %02d:%02d:%02d",
        (1900 + t.tm_year), (t.tm_mon + 1), t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);

    return len;
}
/// 获取当前系统的完整时间(精确到毫秒)
size_t get_minisec_systime(ByteBuilder& timebuff)
{
    const char TIME_FORMAT[] = "%04d-%02d-%02d %02d:%02d:%02d.%03d";
    size_t len = 0;
#ifdef _WIN32
    SYSTEMTIME sysTime;
    GetLocalTime(&sysTime);
    len = timebuff.Format(TIME_FORMAT,
        sysTime.wYear, sysTime.wMonth, sysTime.wDay,
        sysTime.wHour, sysTime.wMinute, sysTime.wSecond, sysTime.wMilliseconds);
#else
    struct timeval tv;
    struct timezone tz;
    tm t;
    size_t minisec = 0;

    gettimeofday(&tv, &tz);

    // VC6下版本
    t = (*localtime(&tv.tv_sec));
    minisec = tv.tv_usec;
    if(minisec > 1000)
        minisec /= 1000;

    len = timebuff.Format(TIME_FORMAT,
        (1900 + t.tm_year), (t.tm_mon + 1), t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, minisec);
#endif
    return len;
}
//--------------------------------------------------------- 
/// 输出当前时间 2018-10-20 13:51:04.560
string _time_now(const char* fmt)
{
    ByteBuilder buff(20);
    get_minisec_systime(buff);
    return string(buff.GetString(), buff.GetLength());
}
/// _hex对ByteArray的重载
string _hex(const ByteArray& buff)
{
    byte b = 0x00;
    ByteBuilder tmp(2 * buff.GetLength());
    for(size_t i = 0;i < buff.GetLength(); ++i)
    {
        b = buff[i] & 0x0F0;
        b >>= HALF_BIT_OFFSET;
        tmp += (b < 0x0A) ? (b + '0') : (b - 0x0A + 'A');

        b = buff[i] & 0x0F;
        tmp += (b < 0x0A) ? (b + '0') : (b - 0x0A + 'A');
    }
    return tmp.GetString();
}
/// _hex对ByteBuilder的重载
string _hex(const ByteBuilder& buff)
{
    const ByteArray& byteArray = buff;
    return _hex(byteArray);
}
//--------------------------------------------------------- 
/// 输出指定数目的空格符号
string _tab(size_t count, size_t tablen, char flag)
{
    ByteBuilder tmp(8);
    tmp.Append(static_cast<byte>(flag), count * tablen);
    return tmp.GetString();
}
//--------------------------------------------------------- 
/// 输出树状图结构
string _tree(size_t lv, char flag, size_t width)
{
    ByteBuilder tmp(8);
    for(size_t i = 0;i < lv; ++i)
    {
        tmp += static_cast<byte>(flag);
        tmp.Append(' ', width - 1);
    }
    return tmp.GetString();
}
/// 输出树状图结点
string _tree_node(size_t lv, char head, char flag, size_t width)
{
    ByteBuilder tmp(8);
    tmp += static_cast<byte>(head);
    tmp.Append(flag, lv * width - 1);
    return tmp.GetString();
}
//--------------------------------------------------------- 
/// 以字符串形式输出bool
string _bool(bool b)
{
    return b ? "true" : "false";
}
//--------------------------------------------------------- 
} // namespace base 
} // namespace zhou_yb
//--------------------------------------------------------- 
#endif // _LIBZHOUYB_ARGPARSER_CPP_
//=========================================================